#ifndef GameObject_H
#define GameObject_H

#include "Ogre.h"

class GameObject : public Ogre::UserDefinedObject {
public:
	GameObject(void);
	~GameObject(void);

	virtual void animate( unsigned long lTimeSinceLastFrame ) = 0;
	
	bool isWorldItem() { return bIsWorldItem; }			// Static objects, like buildings etc.
	bool isInventoryItem() { return bIsInventoryItem; }	// Objects that player can pick up
	bool isUseableItem() { return bIsUseableItem; }		// Objects that player can use other objects on
	bool isCharacter() { return bIsCharacter; }			// Objects that can move itself through the screen

	void defineWorldItem() {
		bIsWorldItem = true;
	}

	void defineInventoryItem() {
		bIsInventoryItem = true;
	}

	void defineUseableItem() {
		bIsUseableItem = true;
	}

	void defineCharacter() {
		bIsCharacter = true;
	}

	// setters
	void setId(unsigned int id) { gmId = id; };
	void setName(Ogre::String name) { gmName = name; };
	void setType(Ogre::String type) { gmType = type; };

	void setModel(Ogre::String modelname, Ogre::String mesh);
	void moveTo(Ogre::Real x, Ogre::Real y, Ogre::Real z); //translate(x,y,z)
	void setPosition(Ogre::Real x, Ogre::Real y, Ogre::Real z);

	void importSceneNode( Ogre::Entity *entity, Ogre::SceneNode *sceneNode );

	void setScale(Ogre::Real x, Ogre::Real y, Ogre::Real z); // min 0, max 1
	void setScaleX(Ogre::Real);
	void setScaleY(Ogre::Real);
	void setScaleZ(Ogre::Real);

	void rotateX(Ogre::Degree dg); // pitch(degree)
	void rotateY(Ogre::Degree dg); // yaw(degree)
	void rotateZ(Ogre::Degree dg); // roll(degree)

	// Getters
	unsigned int getId() { return gmId; }
	Ogre::String getName() { return gmName; }
	Ogre::String getType() { return gmType; }
	Ogre::Entity * getModel() { return gmModel; }
	
	Ogre::Real getPositionX(){ return xPos; }
	Ogre::Real getPositionY(){ return yPos; }
	Ogre::Real getPositionZ(){ return zPos; }

	Ogre::SceneNode * getSceneNode(){ return gmSceneNode; }
	
	//void getScale();
	Ogre::Real getScaleX(){ return xScale; }
	Ogre::Real getScaleY(){ return yScale; }
	Ogre::Real getScaleZ(){ return zScale; }

	Ogre::Degree getRotateX(){ return xRotate; }
	Ogre::Degree getRotateY(){ return yRotate; }
	Ogre::Degree getRotateZ(){ return zRotate; }

	void destroy();

private:
	Ogre::Root           *mRoot;
    Ogre::Camera         *mCamera;
    Ogre::SceneManager   *mSceneMgr;
    //Ogre::Viewport       *mViewport;

	unsigned int	gmId;
	Ogre::String	gmType;
	Ogre::String	gmName;
	Ogre::Entity	*gmModel;	// Mesh file
	Ogre::SceneNode	*gmSceneNode; // this object's root node. Useful, to attach something to it.
	// TODO: List of its subnodes. If this objects consists of more objects.
	// To attach an entity to a specific part.
	// Alternatively: see 'Ogre::Entity::attachObjectToBone(theBone->getName(), theObject, Quaternion, offsetPosition)'

	Ogre::Real		xScale, yScale, zScale;
	Ogre::Real		xPos, yPos, zPos;
	Ogre::Degree	xRotate, yRotate, zRotate;

	bool bIsWorldItem;
	bool bIsInventoryItem;
	bool bIsUseableItem;
	bool bIsCharacter;
};
#endif